package org.wx.thread.interview;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 曾经的面试题：（淘宝？）
 * 实现一个容器，提供两个方法，add，size
 * 写两个线程，线程1添加10个元素到容器中，线程2实现监控元素的个数，当个数到5个时，线程2给出提示并结束
 *
 * 分析下面这个程序，能完成这个功能吗？
 * Synchronized 加锁来保证多线程之间互斥
 */
public class SyncTest {
    volatile List storeList = new ArrayList<String>();


    void add(String str){
        storeList.add(str);
    }

    int size(){
        return storeList.size();
    }

    public static void main(String[] args) {
        final SyncTest twoTest = new SyncTest();


        // 提示5个元素线程
        new Thread(() -> {
            while (true){
                synchronized(twoTest){
                    if(twoTest.size() != 5){
                        try {
                            // 不是5个元素就开始 进入wait队列，等待唤醒
                            twoTest.wait();


                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }else {
                        System.out.println("=======元素到5个了=====");
                        twoTest.notify(); // 通知添加线程启动
                        return;
                    }
                }

            }

        },"notice").start();
        // 让获取线程先启动
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // 添加线程
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                synchronized(twoTest){
                    twoTest.add(Integer.toString(i));
                    System.out.println("添加了元素"+i);

                    if(twoTest.storeList.size() == 5){
                        twoTest.notify();

                        try {
                            twoTest.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        try {
                            TimeUnit.SECONDS.sleep(1);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                    }
                }
            }
        },"add").start();

    }

}
